﻿using System;
using System.Collections;
using System.Reflection;
using System.Globalization;

namespace EOS.Framework.Web.Mvc.Controls
{
    public enum SelectItemValueType
    {
        Value,
        Index
    }

    public class Select : Control
    {
        private IEnumerable enumerable;
        private string itemTextProperty;
        private string itemValueProperty;
        private object selected;
        private bool renderValue;
        private SelectItemValueType itemValueType;
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public SelectItemValueType ItemValueType
        {
            get { return itemValueType; }
            set { itemValueType = value; }
        }

        public bool RenderValue
        {
            get { return renderValue; }
            set { renderValue = value; }
        }

        public object Selected
        {
            get { return selected; }
            set { selected = value; }
        }
	
        public string ItemTextProperty
        {
            get { return itemTextProperty; }
            set { itemTextProperty = value; }
        }

        public string ItemValueProperty
        {
            get { return itemValueProperty; }
            set { itemValueProperty = value; }
        }

        public IEnumerable Enumerable
        {
            get { return enumerable; }
            set { enumerable = value; }
        }

        public Select(IEnumerable enumerable, object selected)
            : this(enumerable, selected, false, SelectItemValueType.Value, null)
        { }

        public Select(IEnumerable enumerable, object selected, bool renderValue)
            : this(enumerable, selected, renderValue, SelectItemValueType.Value, null)
        { }

        public Select(IEnumerable enumerable, object selected, string itemValueProperty)
            : this(enumerable, selected, true, null, itemValueProperty)
        { }

        public Select(IEnumerable enumerable, object selected, bool renderValue, SelectItemValueType optionType)
            : this(enumerable, selected, renderValue, optionType, null)
        { }

        public Select(IEnumerable enumerable, object selected, bool renderValue, SelectItemValueType optionType, string itemTextProperty)
        {
            this.enumerable = enumerable;
            this.selected = selected;
            this.renderValue = renderValue;
            this.itemValueType = optionType;
            this.itemTextProperty = itemTextProperty;
        }

        public Select(IEnumerable enumerable, object selected, bool renderValue, string itemTextProperty, string itemValueProperty)
        {
            this.enumerable = enumerable;
            this.selected = selected;
            this.renderValue = renderValue;
            this.itemTextProperty = itemTextProperty;
            this.itemValueProperty = itemValueProperty;
            this.itemValueType = SelectItemValueType.Value;
        }

        protected override void OnRender(IXhtmlWriter writer, PageContext context)
        {
            if (TagName.ToLower().Equals("select") == false)
            {
                throw new ControlMarkupException(
                    string.Format(CultureInfo.CurrentCulture, Properties.Resources.InvalidTagName, "select"));
            }

            if (string.IsNullOrEmpty(name))
            {
                WriteBeginAttachedTag(writer);
            }
            else
            {
                WriteBeginAttachedTag(writer, new string[] { "name" });
                writer.WriteAttribute("name", name);
            }

            int index = 0;
            foreach (object obj in enumerable)
            {
                object optionName = obj.ToString();
                if (!string.IsNullOrEmpty(itemTextProperty))
                {
                    PropertyInfo namePropertyInfo = obj.GetType().GetProperty(itemTextProperty);
                    if (namePropertyInfo != null)
                    {
                        optionName = namePropertyInfo.GetValue(obj, null);
                    }
                }

                object optionValue = null;
                switch (itemValueType)
                {
                    case SelectItemValueType.Index:
                        optionValue = index;
                        break;
                    case SelectItemValueType.Value:
                        optionValue = obj;
                        if (!string.IsNullOrEmpty(itemValueProperty))
                        {
                            PropertyInfo valuePropertyInfo = obj.GetType().GetProperty(itemValueProperty);
                            if (valuePropertyInfo != null)
                            {
                                optionValue = valuePropertyInfo.GetValue(obj, null);
                            }
                        }
                        break;
                }
                
                writer.WriteStartElement("option");
                if (renderValue)
                {
                    writer.WriteAttribute("value", optionValue.ToString());
                }
                if (selected != null && optionValue.Equals(selected))
                {
                    writer.WriteAttribute("selected", "selected");
                }

                writer.WriteString(optionName.ToString());
                writer.WriteEndElement();

                index++;
            }

            WriteEndAttachedTag(writer);
        }

    }
}
